package com.ruoyi.data.controller;

import com.ruoyi.base.service.IRoomService;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.R;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.data.domain.TdataHtWg;
import com.ruoyi.data.service.ITdataHtWgService;
import com.ruoyi.iot.IotContext;
import com.ruoyi.iot.WebTasksCallBack;
import com.ruoyi.iot.client.NioClient;
import com.ruoyi.iot.domain.CjqMeter;
import com.ruoyi.iot.domain.MeterCallStatus;
import com.ruoyi.iot.domain.vo.MeterCallStatusVo;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.context.request.async.DeferredResult;

import javax.servlet.http.HttpServletResponse;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.CountDownLatch;

/**
 * 违规记录Controller
 *
 * @author ruoyi
 * @date 2024-06-05
 */
@RestController
@RequestMapping("/data/htwg")
@Api(tags = "设备监控-违规记录")
public class TdataHtWgController extends BaseController {
    @Autowired
    private ITdataHtWgService tdataHtWgService;

    @Value("${iot.webTimeOut}")
    private long webTimeOut;

    @Autowired
    private IotContext iotContext;

    @Autowired
    private IRoomService roomService;

    /**
     * 导出违规记录列表
     */
    @ApiOperation("导出违规记录列表")
    @Log(title = "违规记录", businessType = BusinessType.EXPORT)
    @PostMapping("/export")
    public void export(HttpServletResponse response, TdataHtWg tdataHtWg) {
        List<TdataHtWg> list = tdataHtWgService.selectTdataHtWgList(tdataHtWg);
        ExcelUtil<TdataHtWg> util = new ExcelUtil<TdataHtWg>(TdataHtWg.class);
        util.exportExcel(response, list, "违规记录数据");
    }

    @ApiOperation("违规统计分析")
    @Log(title = "违规记录", businessType = BusinessType.EXPORT)
    @GetMapping("/statistics")
    public R<List<TdataHtWg>> getStatistics(TdataHtWg tdataHtWg) {
        return R.ok(tdataHtWgService.getStatistics(tdataHtWg));
    }

    /**
     * 查询违规记录列表
     */
    @GetMapping("/list")
    @ApiOperation("查询违规记录列表")
    public TableDataInfo<TdataHtWg> list(TdataHtWg tdataHtWg) {
        startPage();
        List<TdataHtWg> list = tdataHtWgService.selectHtWgList(tdataHtWg);
        return getDataTable(list);
    }

    /**
     * 违规报警召测
     */
    @PreAuthorize("@ss.hasPermi('data:htwg:call')")
    @GetMapping("/call")
    @ApiOperation("违规记录召测")
    public DeferredResult<AjaxResult> call(@RequestParam("roomIds") List<String> roomIds) {

        List<MeterCallStatus> meterCallStatusList = new CopyOnWriteArrayList<>();
        MeterCallStatusVo meterCallStatusVo = new MeterCallStatusVo().setStatusList(meterCallStatusList);
        final DeferredResult<AjaxResult> deferredResult = new DeferredResult<>(webTimeOut);
        deferredResult.onTimeout(() -> deferredResult.setResult(AjaxResult.success(meterCallStatusVo)));

        List<CjqMeter> cjqMeterList = roomService.selectCjqMeterList(roomIds);
        if (cjqMeterList.isEmpty()) {
            deferredResult.setResult(AjaxResult.success(meterCallStatusVo));
        }
        CountDownLatch countDownLatch = new CountDownLatch(roomIds.size());
        for (CjqMeter cjqMeter : cjqMeterList) {

            MeterCallStatus meterCallStatus = new MeterCallStatus().setRoomId(cjqMeter.getRoomId()).setStatus(1);
            meterCallStatusList.add(meterCallStatus);

            NioClient nioClient = iotContext.getNioClientMap().get(cjqMeter.getCjqNo());
            if (nioClient != null) {
                nioClient.readRelaysState(Integer.valueOf(cjqMeter.getMeterNo()).byteValue(), new WebTasksCallBack(cjqMeter.getRoomId()) {
                    @Override
                    public void callBack(boolean res) {
                        meterCallStatus.setStatus(res ? 0 : 1);
                        countDownLatch.countDown();
                        if (countDownLatch.getCount() == 0) {
                            deferredResult.setResult(AjaxResult.success(meterCallStatusVo));
                        }
                    }
                }.setTdataHtWgService(tdataHtWgService));
            } else {
                countDownLatch.countDown();
            }
            if (countDownLatch.getCount() == 0) {
                deferredResult.setResult(AjaxResult.success(meterCallStatusVo));
            }
            roomIds.remove(cjqMeter.getRoomId());
        }

        for (String roomId : roomIds) {
            MeterCallStatus meterCallStatus = new MeterCallStatus().setRoomId(roomId).setStatus(1);
            meterCallStatusList.add(meterCallStatus);
            countDownLatch.countDown();
            if (countDownLatch.getCount() == 0) {
                deferredResult.setResult(AjaxResult.success(meterCallStatusVo));
            }
        }
        return deferredResult;
    }

    /**
     * 清除违规记录列表
     */
    @PreAuthorize("@ss.hasPermi('data:htwg:clear')")
    @GetMapping("/clear")
    @ApiOperation("清除违规记录列表")
    public AjaxResult clear(@RequestParam("roomIds") List<String> roomIds) {
        tdataHtWgService.clear(roomIds);
        return AjaxResult.success();
    }
}
